迷宫问题的研究与实现

【问题描述】

以一个M×N的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
(1)    根据二维数组,输出迷宫的图形。
(2)    探索迷宫的四个方向:RIGHT为向右,DOWN向下,LEFT向左,UP向上,输出从入口到出口的行走路径。

【算法分析】

主要考查数据结构-栈。栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。

详细请看百度百科: http://baike.baidu.com/subview/38877/12246229.htm?fr=aladdin

【实现分析】

可使用回溯方法,即从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。假如所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。

【代码展示】

1.首先创建一个Point类:

package com.albertshao.study;

public class Point {

	private int x;

	private int y;

	public Point() {

	}

	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}

	@Override
	public String toString() {
		return "Point [x=" + x + ", y=" + y + "]";
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

}
迷宫类: 

package com.albertshao.study;

import java.util.Scanner;
import java.util.Stack;

public class Maze {

	int maze[][];
	private int row = 3;
	private int col = 3;
	Stack<Point> stack;
	boolean p[][] = null;

	public Maze() {

		maze = new int[15][15];
		stack = new Stack<Point>();
		p = new boolean[15][15];
	}

	/*
	 * construct the maze
	 */
	public void init() {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入迷宫的行数");
		row = scanner.nextInt();
		System.out.println("请输入迷宫的列数");
		col = scanner.nextInt();
		System.out.println("请输入" + row + "行" + col + "列的迷宫");
		int temp = 0;
		for (int i = 0; i < row; ++i) {
			for (int j = 0; j < col; ++j) {
				temp = scanner.nextInt();
				maze[i][j] = temp;
				p[i][j] = false;
			}
		}
	}

	/*
	 * list, decide whether there is a road.
	 */
	public void findPath() {
		
		int temp[][] = new int[row + 2][col + 2];
		for (int i = 0; i < row + 2; ++i) {
			for (int j = 0; j < col + 2; ++j) {
				temp[0][j] = 1;
				temp[row + 1][j] = 1;
				temp[i][0] = temp[i][col + 1] = 1;
			}
		}
		
		for(int i = 0; i < row + 2; i ++)
		{
			for(int j = 0; j < col + 2; j ++)
			{
				System.out.print(temp[i][j] + " ");
				
			}
			System.out.println();
		}
		
		// copy the original maze to the new temp.
		for (int i = 0; i < row; ++i) {
			for (int j = 0; j < col; ++j) {
				temp[i + 1][j + 1] = maze[i][j];
			}
		}
		
		System.out.println("after copying data");
		for(int i = 0; i < row + 2; i ++)
		{
			for(int j = 0; j < col + 2; j ++)
			{
				System.out.print(temp[i][j] + " ");
				
			}
			System.out.println();
		}
		//from up-left to skip in the clockWise direction

		int i = 1;
		int j = 1;
		p[i][j] = true;
		stack.push(new Point(i, j));
		while (!stack.empty() && (!(i == (row) && (j == col)))) {

			if ((temp[i][j + 1] == 0) && (p[i][j + 1] == false)) { //turn right 
				p[i][j + 1] = true;
				stack.push(new Point(i, j + 1));
				j++;
			} else if ((temp[i + 1][j] == 0) && (p[i + 1][j] == false)) {  // turn down 
				p[i + 1][j] = true;
				stack.push(new Point(i + 1, j));
				i++;
			} else if ((temp[i][j - 1] == 0) && (p[i][j - 1] == false)) {  // turn left
				p[i][j - 1] = true;
				stack.push(new Point(i, j - 1));
				j--;
			} else if ((temp[i - 1][j] == 0) && (p[i - 1][j] == false)) { // turn up
				p[i - 1][j] = true;
				stack.push(new Point(i - 1, j));
				i--;
			} else {
				stack.pop();
				if (stack.empty()) {
					break;
				}
				i = stack.peek().getX();
				j = stack.peek().getY();
			}

		}

		Stack<Point> newPos = new Stack<Point>();
		if (stack.empty()) {
			System.out.println("没有路径");
		} else {
			System.out.println("有路径");
			System.out.println("路径如下:");
			while (!stack.empty()) {
				Point pos = new Point();
				pos = stack.pop();
				System.out.print("("+pos.getX() + "," + pos.getY()+") ");
				newPos.push(pos);
			}
		}

		/*
		 * print the path
		 */

		String resault[][] = new String[row + 1][col + 1];
		for (int k = 0; k < row; ++k) {
			for (int t = 0; t < col; ++t) {
				resault[k][t] = (maze[k][t]) + "";
			}
		}
		while (!newPos.empty()) {
			Point p1 = newPos.pop();
			resault[p1.getX() - 1][p1.getY() - 1] = "#";

		}

		for (int k = 0; k < row; ++k) {
			for (int t = 0; t < col; ++t) {
				System.out.print(resault[k][t] + "\t");
			}
			System.out.println();
		}
	}

	
	public static void main(String []args) 
	{
		Maze maze = new Maze();
		maze.init();
		maze.findPath();
	}
}

测试结果:

请输入迷宫的行数
3
请输入迷宫的列数
3
请输入3行3列的迷宫
0 1 0
0 0 1
1 0 0 
1 1 1 1 1 
1 0 0 0 1 
1 0 0 0 1 
1 0 0 0 1 
1 1 1 1 1 
after copying data
1 1 1 1 1 
1 0 1 0 1 
1 0 0 1 1 
1 1 0 0 1 
1 1 1 1 1 
有路径
路径如下:
(3,3) 
(3,2) 
(2,2) 
(2,1) 
(1,1) 
#	1	0	
#	#	1	
1	#	#	

备注:部分代码借鉴于网友。

程序在VC++ 6下顺利编译通过。 一、 实验目的: (1) 熟练掌握链栈的基本操作及应用。 (2) 利用链表作为栈的存储结构,设计实现一个求解迷宫的非递归程序。 二、实验内容: 【问题描述】 以一个m×n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对信任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。 【基本要求】 首先实现一个链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出,其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。如:对于下列数据的迷宫,输出的一条通路为:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),……。 【测试数据】 迷宫的测试数据如下:左上角(1,1)为入口,右下角(8,9)为出口。 1 2 3 4 5 6 7 8 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 1 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 0 1 1 1 0 0 0 0 0 0 以方阵形式输出迷宫及其通路。 输出: 请输入迷宫的长和宽:5 5 请输入迷宫内容: 0 1 1 0 0 0 0 1 1 0 1 0 0 1 1 1 0 0 1 0 1 1 0 0 0 迷宫的路径为 括号内的内容分别表示为(行坐标,列坐标,数字化方向,方向) (1,1,1,↓) (2,1,2,→) (2,2,1,↓) (3,2,1,↓) (4,2,2,→) (4,3,1,↓) (5,3,2,→) (5,4,2,→) (5,5,0,) 迷宫路径探索成功!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值